// <copyright file="Repository.cs" company="EnterpriseApi">
// Copyright (c) EnterpriseApi. All rights reserved.
// </copyright>

using System;
using System.Data.Common;
using System.Linq.Expressions;
using EnterpriseApi.Data;
using Microsoft.EntityFrameworkCore;

namespace EnterpriseApi.Repositories;

/// <summary>
/// 通用仓储实现类，提供基本的数据访问操作
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private readonly AppDbContext _context;
    private readonly DbSet<TEntity> _dbSet;

    /// <summary>
    /// 初始化Repository的新实例
    /// </summary>
    /// <param name="context">数据库上下文</param>
    public Repository(AppDbContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
        _dbSet = _context.Set<TEntity>();
    }

    /// <summary>
    /// 获取所有实体
    /// </summary>
    /// <returns>实体集合</returns>
    /// <exception cref="Exception">当获取数据时发生异常</exception>
    public async Task<IEnumerable<TEntity>> GetAllAsync()
    {
        try
        {
            Console.WriteLine($"Repository.GetAllAsync: 尝试获取{typeof(TEntity).Name}类型的所有实体");
            var result = await _dbSet.ToListAsync();
            Console.WriteLine($"Repository.GetAllAsync: 成功获取{result.Count}个{typeof(TEntity).Name}实体");
            return result;
        }
        catch (DbUpdateException dbEx)
        {
            Console.WriteLine($"Repository.GetAllAsync: 数据库更新异常 - {dbEx.Message}");
            if (dbEx.InnerException != null)
            {
                Console.WriteLine($"Repository.GetAllAsync: 内部异常 - {dbEx.InnerException.Message}");
            }
            throw new Exception($"获取{typeof(TEntity).Name}数据时发生数据库更新异常", dbEx);
        }
        catch (DbException dbEx)
        {
            Console.WriteLine($"Repository.GetAllAsync: 数据库异常 - {dbEx.Message}");
            if (dbEx.InnerException != null)
            {
                Console.WriteLine($"Repository.GetAllAsync: 内部异常 - {dbEx.InnerException.Message}");
            }
            throw new Exception($"获取{typeof(TEntity).Name}数据时发生数据库异常", dbEx);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Repository.GetAllAsync: 异常 - {ex.Message}");
            if (ex.InnerException != null)
            {
                Console.WriteLine($"Repository.GetAllAsync: 内部异常 - {ex.InnerException.Message}");
            }
            throw new Exception($"获取{typeof(TEntity).Name}数据时发生异常", ex);
        }
    }

    /// <summary>
    /// 根据条件获取实体
    /// </summary>
    /// <param name="predicate">查询条件</param>
    /// <returns>符合条件的实体集合</returns>
    public async Task<IEnumerable<TEntity>> GetByConditionAsync(Expression<Func<TEntity, bool>> predicate)
    {
        return await _dbSet.Where(predicate).ToListAsync();
    }

    /// <summary>
    /// 根据ID获取实体
    /// </summary>
    /// <param name="id">实体ID</param>
    /// <returns>实体对象，如果不存在则返回null</returns>
    public async Task<TEntity?> GetByIdAsync(int id)
    {
        return await _dbSet.FindAsync(id);
    }

    /// <summary>
    /// 添加实体
    /// </summary>
    /// <param name="entity">要添加的实体</param>
    /// <returns>添加的实体</returns>
    public async Task<TEntity> AddAsync(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException(nameof(entity));
        }

        await _dbSet.AddAsync(entity);
        await _context.SaveChangesAsync();
        return entity;
    }

    /// <summary>
    /// 更新实体
    /// </summary>
    /// <param name="entity">要更新的实体</param>
    /// <returns>更新后的实体</returns>
    public async Task<TEntity> UpdateAsync(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException(nameof(entity));
        }

        _dbSet.Update(entity);
        await _context.SaveChangesAsync();
        return entity;
    }

    /// <summary>
    /// 删除实体
    /// </summary>
    /// <param name="id">要删除的实体ID</param>
    /// <returns>删除是否成功</returns>
    public async Task<bool> DeleteAsync(int id)
    {
        var entity = await _dbSet.FindAsync(id);
        if (entity == null)
        {
            return false;
        }

        _dbSet.Remove(entity);
        await _context.SaveChangesAsync();
        return true;
    }

    /// <summary>
    /// 保存更改到数据库
    /// </summary>
    /// <returns>受影响的行数</returns>
    public async Task<int> SaveChangesAsync()
    {
        return await _context.SaveChangesAsync();
    }
}